Please enable JavaScript to view this website.

Skip to main content

Device-Triggered Rotation

The device should initiate rotation of its operational certificate when it detects that the certificate is approaching expiration. The device should run this check on every boot and complete any in-flight MQTT operations before disconnecting to rotate. Because the operational certificate has a 1-year lifetime and the rotation window opens at 30 days, there is no urgency within a single session; the device does not need to interrupt an active operation.

The device should rotate when any of the following apply:

  • Operational certificate is within 30 days of expiration
  • An unexpected disconnect is followed by repeated reconnect failures, suggesting the certificate may have been revoked. On MQTT 3.1.1 stacks (the most common embedded case), DISCONNECT packets carry no reason code. On MQTT 5.0 stacks, reason code 135 (Not Authorized) is the explicit revocation signal. In both cases, treat any unexpected disconnect accompanied by repeated reconnect failures as a potential revocation signal and attempt rotation.
  • Certificate may have been compromised

Expiry Check

Check the notAfter field on every boot. The example below uses Python's cryptography library to illustrate the logic. Adapt it to your TLS stack's certificate parsing API (e.g. mbedtls_x509_crt_parse + valid_to in mbedTLS, or wolfSSL_X509_get_notAfter in wolfSSL):

from datetime import datetime, timedelta, timezone
from cryptography import x509

def should_rotate(cert_pem: str, threshold_days: int = 30) -> bool:
cert = x509.load_pem_x509_certificate(cert_pem.encode())
return cert.not_valid_after_utc <= datetime.now(timezone.utc) + timedelta(days=threshold_days)

Rotation Sequence

Rotation Steps

  1. Complete any in-flight MQTT operations, then disconnect from the current operational session
  2. Connect using the bootstrap certificate
  3. Follow the Phase 2 flow to get a new certificate and ownership token. RegisterThing during rotation behaves the same as during initial provisioning — because the Thing already exists, the provisioning template attaches the new certificate to the existing Thing rather than creating a new one.
  4. Store the new certificate and private key in secure storage
  5. Disconnect from bootstrap session and reconnect with the new operational certificate
  6. Resubscribe explicitly to $aws/things/{MPBID}/jobs/notify-next after reconnecting. Do not rely on the broker restoring persistent session subscriptions across a certificate switch
  7. Verify shadow access works: this confirms the new certificate is active and policies are attached
  8. The platform handles old certificate cleanup automatically. The device does not need to deactivate or delete the old certificate.

Failure and Recovery

If rotation fails at any step, the device should:

  1. Reconnect using the old operational certificate (if it is still within its validity period)
  2. On the next boot, re-run the expiry check. If the condition still applies, attempt rotation again.

The device should not retry indefinitely within a single session. One attempt per boot is sufficient.

If the old certificate has already expired: the device cannot reconnect with the operational certificate at all. Connect directly with the bootstrap certificate, re-attempt the Phase 2 provisioning flow to obtain a new certificate, then reconnect with the new operational certificate.

Crash during rotation: If the device crashes after storing the new certificate but before completing reconnection, on reboot it should attempt to connect with the new certificate first. If that succeeds, rotation is complete. If it fails, fall back to the old certificate and retry rotation on the next boot.